package rpc

import (
	"context"
	"crypto/tls"
	"fmt"
	"net"
	"sync"
	"time"

	"github.com/tjfoc/gmsm/gmtls"
	"storj.io/drpc/drpcconn"
)

type TcpDialer struct {
	// DialTimeout causes all the tcp dials to error if they take longer
	// than it if it is non-zero.
	DialTimeout time.Duration
	//cache       map[string]*drpcconn.Conn
	cache    sync.Map
	useCache bool
}

// NewTcpDialer returns a Dialer with default options set.
func NewTcpDialer(useCache bool) *TcpDialer {
	fmt.Println("NewTcpDialer")
	return &TcpDialer{
		DialTimeout: 60 * time.Second,
		useCache:    useCache,
	}
}
func (d *TcpDialer) DialNode(ctx context.Context, port uint16, insecure bool) (*drpcconn.Conn, error) {
	addr := fmt.Sprintf("127.0.0.1:%d", port)

	if d.useCache {
		if val, ok := d.cache.Load(addr); ok {
			return val.(*drpcconn.Conn), nil
		}
	}

	conf := &gmtls.Config{
		//InsecureSkipVerify: true,
	}
	//conn, err := d.DialAddress(ctx, addr)
	conn, err := gmtls.Dial("tcp", addr, conf)
	if err != nil {
		return nil, err
	}

	drpcConn := drpcconn.New(conn)
	if d.useCache {
		d.cache.Store(addr, drpcConn)
	}
	return drpcConn, nil
}
func (d *TcpDialer) DialAddress(ctx context.Context, addr string) (conn net.Conn, err error) {
	c, err := net.DialTimeout("tcp", addr, time.Second*6)
	if err != nil {
		return nil, err
	}
	return c, nil
}

func (d *TcpDialer) DialTLS(ctx context.Context, addr string) (conn net.Conn, err error) {
	ctx2, cancel := context.WithTimeout(ctx, 10*time.Second)
	defer cancel()
	tlsDialer := tls.Dialer{
		Config: &tls.Config{
			//InsecureSkipVerify: true,
		},
	}
	c, err := tlsDialer.DialContext(ctx2, "tcp", addr)
	return c, err
}

//如果是本地地址，以devid作为缓存key,如果是公网Ip,以公网ip作为缓存
func (d *TcpDialer) DialAddressWithPool(ctx context.Context, addr string) (conn net.Conn, err error) {
	return nil, nil
}
